﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using RedBit.OAuthLibrary;
using TradeMeSDK;

namespace TradeMo
{
    public class SearchResultsViewModel  : BaseViewModel
    {
        private SearchType _searchType;
        private ISearchResultsView _view;

        public static List<SelectorItem<SearchType>> SearchTypes { get; set; }
        public static SelectorItem<SearchType> General = new SelectorItem<SearchType> { Title = "General", Picture = "/Images/general.png", Item = SearchType.General };
        public static SelectorItem<SearchType> UsedCars = new SelectorItem<SearchType> { Title = "Used Cars", Picture = "/Images/car.png", Item = SearchType.UsedCars };
        public static SelectorItem<SearchType> Boats = new SelectorItem<SearchType> { Title = "Boats", Picture = "/Images/boat.png", Item = SearchType.Boats };
        public static SelectorItem<SearchType> Bikes = new SelectorItem<SearchType> { Title = "Bikes", Picture = "/Images/motorbike.png", Item = SearchType.Bikes };
        public static SelectorItem<SearchType> Jobs = new SelectorItem<SearchType> { Title = "Jobs", Picture = "/Images/jobs.png", Item = SearchType.Jobs };
        public static SelectorItem<SearchType> Residential = new SelectorItem<SearchType> { Title = "Residential", Picture = "/Images/property.png", Item = SearchType.Residential };
        public static SelectorItem<SearchType> Rental = new SelectorItem<SearchType> { Title = "Rental", Picture = "/Images/property.png", Item = SearchType.Rental };
        public static SelectorItem<SearchType> OpenHomes = new SelectorItem<SearchType> { Title = "Open Homes", Picture = "/Images/property.png", Item = SearchType.OpenHomes };
        public static SelectorItem<SearchType> Flatmates = new SelectorItem<SearchType> { Title = "Flatmates", Picture = "/Images/property.png", Item = SearchType.Flatmates };
        //public static SelectorItem<SearchType> Rural = new SelectorItem<SearchType> { Title = "Rural", Picture = "/Images/property.png", Item = SearchType.Rural };
        //public static SelectorItem<SearchType> Lifestyle = new SelectorItem<SearchType> { Title = "Lifestyle", Picture = "/Images/property.png", Item = SearchType.Lifestyle };
        //public static SelectorItem<SearchType> Retirement = new SelectorItem<SearchType> { Title = "Retirement", Picture = "/Images/property.png", Item = SearchType.Retirement };
        //public static SelectorItem<SearchType> Commercial = new SelectorItem<SearchType> { Title = "Commercial", Picture = "/Images/commercial.png", Item = SearchType.Commercial };
        //public static SelectorItem<SearchType> CommercialLease = new SelectorItem<SearchType> { Title = "Commercial Lease", Picture = "/Images/commercial.png", Item = SearchType.CommercialLease };

        static SearchResultsViewModel()
        {
            SearchTypes = new List<SelectorItem<SearchType>>
                       {
                           General, 
                           UsedCars, 
                           Boats, Bikes, Jobs,
                           Residential, Rental, OpenHomes, Flatmates,
                           // Rural, Lifestyle, Retirement, Commercial, CommercialLease
                       };
        }

        public SearchResultsViewModel(ISearchResultsView view)
        {
            _view = view;
        }



        private GeneralSearchCriteriaViewModel _generalSearchCriteriaModel;
        public GeneralSearchCriteriaViewModel GeneralSearchCriteriaModel
        {
            get
            {
                return _generalSearchCriteriaModel ??
                       (_generalSearchCriteriaModel = new GeneralSearchCriteriaViewModel());
            }
            set { _generalSearchCriteriaModel = value; }
        }

    	private CriteriaBikesViewModel _criteriaBikesModel;
    	public CriteriaBikesViewModel CriteriaBikesModel
    	{
    		get { return _criteriaBikesModel ?? (_criteriaBikesModel = new CriteriaBikesViewModel()); }
    		set { _criteriaBikesModel = value; }
    	}

    	private CriteriaUsedCarsViewModel _criteriaUsedCarsModel;
    	public CriteriaUsedCarsViewModel CriteriaUsedCarsModel
    	{
    		get { return _criteriaUsedCarsModel ?? (_criteriaUsedCarsModel = new CriteriaUsedCarsViewModel()); }
    		set { _criteriaUsedCarsModel = value; }
    	}

        private CriteriaBoatsViewModel _criteriaBoatsModel;
        public CriteriaBoatsViewModel CriteriaBoatsModel
        {
            get { return _criteriaBoatsModel ?? (_criteriaBoatsModel = new CriteriaBoatsViewModel()); }
            set { _criteriaBoatsModel = value; }
        }

        private CriteriaJobsViewModel _criteriaJobsModel;
        public CriteriaJobsViewModel CriteriaJobsModel
        {
            get { return _criteriaJobsModel ?? (_criteriaJobsModel = new CriteriaJobsViewModel()); }
            set { _criteriaJobsModel = value; }
        }

        private CriteriaPropertyForSaleViewModel _criteriaPropertyForSaleModel;
        public CriteriaPropertyForSaleViewModel CriteriaPropertyForSaleModel
        {
            get
            {
                return _criteriaPropertyForSaleModel ??
                       (_criteriaPropertyForSaleModel = new CriteriaPropertyForSaleViewModel());
            }
            set { _criteriaPropertyForSaleModel = value; }
        }

        private CriteriaPropertyRentalViewModel _criteriaPropertyRentalModel;
        public CriteriaPropertyRentalViewModel CriteriaPropertyRentalModel
        {
            get
            {
                return _criteriaPropertyRentalModel ??
                       (_criteriaPropertyRentalModel = new CriteriaPropertyRentalViewModel());
            }
            set { _criteriaPropertyRentalModel = value; }
        }

        private CriteriaPropertyForSaleViewModel _criteriaPropertyOpenHomeModel;
        public CriteriaPropertyForSaleViewModel CriteriaPropertyOpenHomeModel
        {
            get
            {
                return _criteriaPropertyOpenHomeModel ??
                       (_criteriaPropertyOpenHomeModel = new CriteriaPropertyForSaleViewModel());
            }
            set { _criteriaPropertyOpenHomeModel = value; }
        }

        private CriteriaPropertyFlatmateViewModel _criteriaPropertyFlatmateModel;
        public CriteriaPropertyFlatmateViewModel CriteriaPropertyFlatmateModel
        {
            get
            {
                return _criteriaPropertyFlatmateModel ??
                       (_criteriaPropertyFlatmateModel = new CriteriaPropertyFlatmateViewModel());
            }
            set { _criteriaPropertyFlatmateModel = value; }
        }


        private SelectorItem<SearchType> _selectedSearchTypeSelector;
        public SelectorItem<SearchType> SelectedSearchTypeSelector
        {
            get { return _selectedSearchTypeSelector ?? (_selectedSearchTypeSelector = General); }
            set
            {
                _selectedSearchTypeSelector = value ?? General;
                ClearSearch();
                NotifyPropertyChanged("SearchTypeName");
                NotifyPropertyChanged("SearchTypeImage");
            }
        }

        public string SearchTypeImage
        {
            get
            {
                return SelectedSearchTypeSelector != null ? SelectedSearchTypeSelector.Picture : "";
            }
        }

        public string SearchTypeName
        {
            get
            {
                return SelectedSearchTypeSelector != null ? SelectedSearchTypeSelector.Title : "";
            }
        }

        private string _searchString;
        public string SearchString
        {
            get { return _searchString; }
            set { _searchString = value; NotifyPropertyChanged("SearchString"); }
        }


        private ObservableCollection<SearchResultItem> _searchResults;
        public ObservableCollection<SearchResultItem> SearchResults
        {
            get { return _searchResults ?? (_searchResults = new ObservableCollection<SearchResultItem>()); }
        }

        private bool _isSearching;
        public bool IsSearching
        {
            get { return _isSearching; }
            set { _isSearching = value; NotifyPropertyChanged("IsSearching"); }
        }


        public void ClearSearch()
        {
            SearchResults.Clear();
            SetTotalCount(0);
            SetDidYouMean(null);
            SetLoadMore(0, 0);

            GeneralSearchCriteriaModel.Criteria.PageNumber = 0;
        }

        public void DoSearch()
        {
            ClearSearch();
            IsSearching = true;
            switch(_searchType)
            {
                case SearchType.General:
                    App.Model.Recent.AddRecentSearch(GeneralSearchCriteriaModel.Criteria);
                    App.TradeMe.Search.General(GeneralSearchCriteriaModel.Criteria, OnSearchResults);
                    break;
				case SearchType.Bikes:
					App.Model.Recent.AddRecentSearch(CriteriaBikesModel.Criteria);
					App.TradeMe.Search.MotorBikes(CriteriaBikesModel.Criteria, OnSearchResults);
            		break;
				case SearchType.UsedCars:
            		App.Model.Recent.AddRecentSearch(CriteriaUsedCarsModel.Criteria);
					App.TradeMe.Search.UsedMotors(CriteriaUsedCarsModel.Criteria, OnSearchResults);
            		break;
                case SearchType.Boats:
                    App.Model.Recent.AddRecentSearch(CriteriaBoatsModel.Criteria);
                    App.TradeMe.Search.Boats(CriteriaBoatsModel.Criteria, OnSearchResults);
                    break;
                case SearchType.Jobs:
                    App.Model.Recent.AddRecentSearch(CriteriaJobsModel.Criteria);
                    App.TradeMe.Search.Jobs(CriteriaJobsModel.Criteria, OnSearchResults);
                    break;
                case SearchType.Residential:
                    App.Model.Recent.AddRecentSearch(CriteriaPropertyForSaleModel.Criteria);
                    App.TradeMe.Search.ResidentialProperties(CriteriaPropertyForSaleModel.Criteria, OnSearchResults);
                    break;
                case SearchType.Rental:
                    App.Model.Recent.AddRecentSearch(CriteriaPropertyRentalModel.Criteria);
                    App.TradeMe.Search.RentalProperties(CriteriaPropertyRentalModel.Criteria, OnSearchResults);
                    break;
                case SearchType.OpenHomes:
                    App.Model.Recent.AddRecentSearch(CriteriaPropertyOpenHomeModel.Criteria);
                    App.TradeMe.Search.OpenHomes(CriteriaPropertyOpenHomeModel.Criteria, OnSearchResults);
                    break;
                case SearchType.Flatmates:
                    App.Model.Recent.AddRecentSearch(CriteriaPropertyFlatmateModel.Criteria);
                    App.TradeMe.Search.Flatmates(CriteriaPropertyFlatmateModel.Criteria, OnSearchResults);
                    break;
            }
        }

        public bool BeginSearch(string searchType, string criteriaHash)
        {
            switch (searchType)
            {
                case "general":
                    _searchType = SearchType.General;
            		SelectedSearchTypeSelector = General;
                    GeneralSearchCriteriaModel.Criteria = new IsolatedStorageRepository<SearchGeneralCriteria>(criteriaHash + ".criteria").Get();
                    SearchString = GeneralSearchCriteriaModel.Criteria.SearchString;
                    DoSearch();
                    return true;

                case "category":
                    _searchType = SearchType.General;
            		SelectedSearchTypeSelector = General;
                    GeneralSearchCriteriaModel.Criteria = new IsolatedStorageRepository<SearchGeneralCriteria>(criteriaHash + ".criteria").Get();
                    SearchString = App.TradeMe.CategoryName(GeneralSearchCriteriaModel.Criteria.Category);
                    DoSearch();
                    return true;

				case "bikes":
            		_searchType = SearchType.Bikes;
            		SelectedSearchTypeSelector = Bikes;
            		CriteriaBikesModel.Criteria = new IsolatedStorageRepository<SearchMotorBikesCriteria>(criteriaHash + ".criteria").Get();
            		SearchString = CriteriaBikesModel.Criteria.SearchString;
					DoSearch();
            		return true;

				case "usedcars":
            		_searchType = SearchType.UsedCars;
            		SelectedSearchTypeSelector = UsedCars;
					CriteriaUsedCarsModel.Criteria = new IsolatedStorageRepository<SearchUsedMotorsCriteria>(criteriaHash + ".criteria").Get();
            		SearchString = CriteriaUsedCarsModel.Criteria.SearchString;
					DoSearch();
            		return true;

                case "boats":
            		_searchType = SearchType.Boats;
            		SelectedSearchTypeSelector = Boats;
					CriteriaBoatsModel.Criteria = new IsolatedStorageRepository<SearchBoatsCriteria>(criteriaHash + ".criteria").Get();
            		SearchString = CriteriaBoatsModel.Criteria.SearchString;
					DoSearch();
                    return true;

                case "jobs":
                    _searchType = SearchType.Jobs;
                    SelectedSearchTypeSelector = Jobs;
                    CriteriaJobsModel.Criteria = new IsolatedStorageRepository<SearchJobsCriteria>(criteriaHash + ".criteria").Get();
            		SearchString = CriteriaJobsModel.Criteria.SearchString;
					DoSearch();
                    return true;

                case "residential":
                    _searchType = SearchType.Residential;
                    SelectedSearchTypeSelector = Residential;
                    var isr = new IsolatedStorageRepository<SearchResidentialCriteria>(criteriaHash + ".criteria");
                    CriteriaPropertyForSaleModel.Criteria = isr.Get();
            		SearchString = CriteriaPropertyForSaleModel.Criteria.SearchString;
					DoSearch();
                    return true;

                case "rental":
                    _searchType = SearchType.Rental;
                    SelectedSearchTypeSelector = Rental;
                    CriteriaPropertyRentalModel.Criteria = new IsolatedStorageRepository<SearchResidentialCriteria>(criteriaHash + ".criteria").Get();
                    SearchString = CriteriaPropertyRentalModel.Criteria.SearchString;
                    DoSearch();
                    return true;

                case "openhome":
                    _searchType = SearchType.OpenHomes;
                    SelectedSearchTypeSelector =OpenHomes;
                    CriteriaPropertyOpenHomeModel.Criteria = new IsolatedStorageRepository<SearchResidentialCriteria>(criteriaHash + ".criteria").Get();
                    SearchString = CriteriaPropertyOpenHomeModel.Criteria.SearchString;
                    DoSearch();
                    return true;

                case "flatmate":
                    _searchType = SearchType.Flatmates;
                    SelectedSearchTypeSelector = Flatmates;
                    CriteriaPropertyFlatmateModel.Criteria = new IsolatedStorageRepository<SearchResidentialCriteria>(criteriaHash + ".criteria").Get();
                    SearchString = CriteriaPropertyFlatmateModel.Criteria.SearchString;
                    DoSearch();
                    return true;

                default:
                    MessageBox.Show("Coming soon");
                    return false;
            }

        }

        public void DoSearchMore()
        {
            IsSearching = true;
            SetLoadMore(0, 0);

            switch (_searchType)
            {
                case SearchType.General:
            		GeneralSearchCriteriaModel.Criteria.PageNumber = 
							GeneralSearchCriteriaModel.Criteria.PageNumber == 0 
									? 2
            						: GeneralSearchCriteriaModel.Criteria.PageNumber + 1;
            		App.TradeMe.Search.General(GeneralSearchCriteriaModel.Criteria, OnSearchResults);
                    break;

				case SearchType.Bikes:
            		CriteriaBikesModel.Criteria.PageNumber = CriteriaBikesModel.Criteria.PageNumber == 0
            		                ? 2
            		                : CriteriaBikesModel.Criteria.PageNumber + 1;
					App.TradeMe.Search.MotorBikes(CriteriaBikesModel.Criteria, OnSearchResults);
            		break;

				case SearchType.UsedCars:
            		CriteriaUsedCarsModel.Criteria.PageNumber = CriteriaUsedCarsModel.Criteria.PageNumber == 0
            		                ? 2
            		                : CriteriaUsedCarsModel.Criteria.PageNumber + 1;
					App.TradeMe.Search.UsedMotors(CriteriaUsedCarsModel.Criteria, OnSearchResults);
            		break;

                case SearchType.Boats:
                    CriteriaBoatsModel.Criteria.PageNumber = CriteriaBoatsModel.Criteria.PageNumber == 0
                                    ? 2
                                    : CriteriaBoatsModel.Criteria.PageNumber + 1;
                    break;

                case SearchType.Jobs:
                    CriteriaJobsModel.Criteria.PageNumber = CriteriaJobsModel.Criteria.PageNumber == 0
                                    ? 2
                                    : CriteriaJobsModel.Criteria.PageNumber + 1;
                    break;

                case SearchType.Residential:
                    CriteriaPropertyForSaleModel.Criteria.PageNumber = CriteriaPropertyForSaleModel.Criteria.PageNumber == 0
                                    ? 2
                                    : CriteriaPropertyForSaleModel.Criteria.PageNumber + 1;
                    break;

                case SearchType.Rental:
                    CriteriaPropertyRentalModel.Criteria.PageNumber = CriteriaPropertyRentalModel.Criteria.PageNumber == 0
                                    ? 2
                                    : CriteriaPropertyRentalModel.Criteria.PageNumber + 1;
                    break;

                case SearchType.OpenHomes:
                    CriteriaPropertyOpenHomeModel.Criteria.PageNumber = CriteriaPropertyOpenHomeModel.Criteria.PageNumber == 0
                                    ? 2
                                    : CriteriaPropertyOpenHomeModel.Criteria.PageNumber + 1;
                    break;

                case SearchType.Flatmates:
                    CriteriaPropertyFlatmateModel.Criteria.PageNumber = CriteriaPropertyFlatmateModel.Criteria.PageNumber == 0
                                    ? 2
                                    : CriteriaPropertyFlatmateModel.Criteria.PageNumber + 1;
                    break;


                default:
                    IsSearching = false;
                    break;
            }
        }

        public static SearchResultItem LoadMore = new SearchResultItem { Message = "Load More ..." };

        private void OnSearchResults(BaseEventArgs<SearchResults> results)
        {
            IsSearching = false;
            if (results.IsError)
            {
                MessageBox.Show("Bugger: Unable to show results");
                return;
            }

            var searchResults = results.Response;

            SetTotalCount(searchResults.TotalCount);
            SetDidYouMean(searchResults.DidYouMean);

            SearchResultItem lastObject = null;
            if (SearchResults.Contains(LoadMore))
            {
                SearchResults.Remove(LoadMore);
                lastObject = SearchResults[SearchResults.Count - 2];
            }

            foreach (var listing in searchResults.List)
                SearchResults.Add(SearchResultItem.Build(listing));

            SetLoadMore(searchResults.TotalCount, SearchResults.Count);

            if (lastObject != null)
            {
                _view.SetLastSearchResultItem(lastObject);
            }
        }

        private void SetTotalCount(int count)
        {
            TotalCount = count == 0 ? "" : "Total Count: " + count;
        }

        private void SetDidYouMean(string value)
        {
            _didYouMeanText = value;
            if (string.IsNullOrEmpty(value))
                DidYouMean = "";
            else
                DidYouMean = "Did you mean: " + value + "?";
        }

        private string _totalCount;
        public string TotalCount
        {
            get { return _totalCount; }
            set { _totalCount = value; NotifyPropertyChanged("TotalCount"); }
        }

        private string _didYouMean;
        public string DidYouMean
        {
            get { return _didYouMean; }
            set { _didYouMean = value; NotifyPropertyChanged("DidYouMean"); NotifyPropertyChanged("ShowDidYouMean"); }
        }

        private string _didYouMeanText;
        public bool ShowDidYouMean { get { return !string.IsNullOrEmpty(DidYouMean); } }

        private void SetLoadMore(int totalCount, int currentCount)
        {
            if (currentCount < totalCount)
                SearchResults.Add(LoadMore);
        }

        public void ChangeSearchToDidYouMean()
        {
            GeneralSearchCriteriaModel.Criteria.SearchString = _didYouMeanText;
            DoSearch();
        }
    }
}
